/**
 * 存储用户信息
 */
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
import { Md5 } from 'ts-md5';
import type * as Global from 'src/types/global';
import {
  NO_QUALIFICATION_FIELD_VALUE,
  NO_PARTICIPATION_FIELD_VALUE,
} from 'src/constants';

/* ___ _ ___ */
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;

@Injectable({
  providedIn: 'root',
})
export class BaseService {
  public usertoken: string; //token
  public roomid: string; //roomid
  public versionCode: number;
  public os: number = 3; //3代表web
  public osVersion: string = ''; //版本号
  public imei: string = ''; //生成的唯一码
  public ncode: any; //seed + imei + os + reqtime
  public userid: string; //
  public time;
  constructor() {}
  //获取加密的MD5，进行两次md5加密 PC加密
  public getMd5NcodePC(reqtime: any) {
    this.ncode = Md5.hashStr(
      environment._s_s +
        '' +
        this.getImei() +
        '' +
        this.os +
        '' +
        this.getBrowserVersion() +
        '' +
        reqtime,
      false
    );
    this.ncode = Md5.hashStr((this.ncode + '').toUpperCase(), false);
    return (this.ncode + '').toUpperCase();
  }

  //获取加密的MD5，进行两次md5加密 APP加密
  public getMd5NcodeAPP(reqtime: any) {
    this.ncode = Md5.hashStr(
      environment.seed + '' + this.imei + '' + this.os + '' + reqtime,
      false
    );
    this.ncode = Md5.hashStr(this.ncode.toUpperCase(), false);
    return this.ncode.toUpperCase();
  }
  //图片地址
  public getDeployUrl() {
    return environment.deployUrl;
  }
  public setUserToken(usertoken: string): void {
    this.usertoken = usertoken;
  }
  public getUserToken(): string {
    return this.usertoken;
  }
  public setRoomid(roomid: string): void {
    this.roomid = roomid;
  }
  public getRoomid(): string {
    return this.roomid;
  }
  public setUserid(userid: string): void {
    this.userid = userid;
  }
  public getUserid(): string {
    return this.userid;
  }
  public getCurrentId() {
    if (this.roomid == '0') {
      return this.userid;
    } else {
      return this.roomid;
    }
  }
  public getBrowserVersion() {
    this.osVersion = this.getBrowser() + '';
    return this.osVersion;
  }
  public getBrowser() {
    var agent = (navigator.userAgent + '').toLowerCase();
    var regStr_ie = /msie [\d.]+;/gi;
    var regStr_ff = /firefox\/[\d.]+/gi;
    var regStr_chrome = /chrome\/[\d.]+/gi;
    var regStr_saf = /safari\/[\d.]+/gi;

    //IE
    if (agent.indexOf('msie') > 0) {
      return agent.match(regStr_ie);
    }
    if (agent.indexOf('rv:11.0') > 0) {
      return 'IE11';
    }
    //firefox
    if (agent.indexOf('firefox') > 0) {
      return agent.match(regStr_ff);
    }

    //Chrome
    if (agent.indexOf('chrome') > 0) {
      return agent.match(regStr_chrome);
    }
    //Safari
    if (agent.indexOf('safari') > 0 && agent.indexOf('chrome') < 0) {
      return agent.match(regStr_saf);
    }
  }
  public setImei(imei: any) {
    this.imei = imei;
  }
  public getImei() {
    return this.imei;
  }
  /**
   * 吐司方法
   * @param msg
   * @param duration
   */
  public showToast(msg: string, duration: number) {
    duration = isNaN(duration) ? 2000 : duration;
    if (document.getElementById('toastdiv')) {
      document.body.removeChild(document.getElementById('toastdiv'));
    }
    clearTimeout(this.time);
    this.time = null;
    var m = document.createElement('div');
    m.id = 'toastdiv';
    m.innerHTML = msg;
    m.style.cssText =
      'width:62%; min-width:180px;font-size:14px; background:#000; opacity:0.6; height:auto;min-height: 30px; color:#fff; line-height:30px; text-align:center; border-radius:4px; position:fixed; top:60%; left:20%; z-index:999999;';
    document.body.appendChild(m);
    this.time = setTimeout(function () {
      var d = 0.5;
      m.style.webkitTransition =
        '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
      m.style.opacity = '0';
      setTimeout(function () {
        if (document.getElementById('toastdiv')) {
          document.body.removeChild(document.getElementById('toastdiv'));
        }
      }, d * 1000);
    }, duration);
  }
  /**
   * 判断是不是电脑直播
   * @param ispc
   */
  public getIsPc() {
    var userAgentInfo = navigator.userAgent;
    var Agents = [
      'Android',
      'iPhone',
      'SymbianOS',
      'Windows Phone',
      'iPad',
      'iPod',
    ];
    var flag = true;
    for (var v = 0; v < Agents.length; v++) {
      if (userAgentInfo.indexOf(Agents[v]) > 0) {
        flag = false;
        break;
      }
    }
    return flag;
  }
  public setVersionCode(versionCode: number) {
    this.versionCode = versionCode;
  }

  public getVersionCode() {
    return this.versionCode;
  }

  /**
   * @param startTime
   * @param endTime
   * @description: 获取 config 的状态
   */
  public useConfigStatus(startTime: number, endTime: number): 1 | 2 | 3 {
    const now = Date.now();
    let status: 1 | 2 | 3;

    if (now < startTime) {
      status = 1;
    } else if (now > startTime && now < endTime) {
      status = 2;
    } else {
      status = 3;
    }
    return status;
  }

  /**
   * @param all 所有榜单列表
   * @param type 榜单对应 type1 type2 ...
   * @description: 根据 type 获取页面活动状态
   */
  useStatusWithTargetTypes(
    all: Global.IConfig[],
    ...childrenTypes: number[]
  ): EndYear.ITAB[] {
    const targetConfigs = all
      .filter((config) => childrenTypes.includes(config.type))
      .sort((i, j) => i.startTime - j.startTime); /* 开始时间 小到大 */

    // TODEL:FOR LOG TEST
    console.table(
      targetConfigs.map((item) => {
        return {
          ...item,
          start_time: new Date(item.startTime * 1000).toLocaleString(),
          end_time: new Date(item.endTime * 1000).toLocaleString(),
        };
      }),
      ['id', 'type', 'name', 'start_time', 'end_time']
    );

    const configMap = new Map<number, EndYear.ITAB>();

    for (
      let index = 0, activeIndex = 0;
      index < targetConfigs.length;
      index++
    ) {
      const config = targetConfigs[index];

      const { type, startTime, endTime, id } = config;

      if (!configMap.has(type)) {
        // 不存在
        const item = {
          status: this.useConfigStatus(startTime * 1000, endTime * 1000),
          key: configMap.size + 1 /* 1,2,3 */,
          type,
          startTime,
          endTime,
          activeKey: 0,
          stageId: id,
        };
        // 重置
        activeIndex = 0;

        configMap.set(type, item);
      } else {
        //  已存在
        activeIndex++;
        const curStatus = this.useConfigStatus(
          startTime * 1000,
          endTime * 1000
        );
        const tartgetConfig = configMap.get(type);
        if (tartgetConfig.status !== 2) {
          tartgetConfig.status = curStatus;
        }
        if (curStatus === 2 || curStatus === 3) {
          /* 更新对应参数 */
          configMap.set(type, {
            ...configMap.get(type),
            startTime,
            endTime,
            stageId: id,
          });
        }

        if (curStatus === 2) {
          /* 进行中 更新对应参数 */
          configMap.set(type, {
            ...configMap.get(type),
            activeKey: activeIndex,
          });

          break;
        }
      }
    }

    // TODEL:FOR LOG TEST
    console.table(
      Array.from(configMap.values()).map((item) => {
        return {
          ...item,
          start_time: new Date(item.startTime * 1000).toLocaleString(),
          end_time: new Date(item.endTime * 1000).toLocaleString(),
        };
      }),
      ['id', 'status', 'type', 'name', 'start_time', 'end_time']
    );
    return Array.from(configMap.values());
  }

  // 未开始-倒计时
  public useStartTimeCounDown(endTime, resolve, reject) {
    const now = Date.now();
    const differTime = endTime - now;
    if (differTime < 0) {
      // TODEL:FOR LOG
      console.log('该时刻已经过去', new Date(endTime).toLocaleString());
      return reject();
    }
    if (differTime >= 0) {
      const times = [
        Math.floor((differTime % DAY) / HOUR),
        Math.floor((differTime % HOUR) / MINUTE),
        Math.floor((differTime % MINUTE) / SECOND),
      ].map((t) => [Math.floor(t / 10), t % 10]) as Global.ITimes;

      resolve(times);
    }
  }

  /**
   * @param dom
   * @param cb
   * @description: 检查目标可见性
   */
  useIntersectionObserver(
    dom: HTMLLIElement,
    cb: (visibility: boolean) => void,
    option?: IntersectionObserverInit
  ): IntersectionObserver {
    var intersectionObserver = new IntersectionObserver(
      function (entries) {
        // console.log('entries=>', entries);
        // If intersectionRatio is 0, the target is out of view
        // and we do not need to do anything.
        if (entries[0].intersectionRatio <= 0) {
          cb(false);
          // console.log('IntersectionObserver:', '隐藏');
          return;
        }

        cb(true);
        // console.log('IntersectionObserver:', '出现');
      },
      {
        threshold: 0.0,
        rootMargin: '0px 0px -70px 0px' /* 向上可见70px再触发 */,
        ...option,
      }
    );
    // start observing
    intersectionObserver.observe(dom);
    return intersectionObserver;
  }

  /**
   * @param sign 存储name
   * @description: 今日是否有效
   */
  useTodayCheck(sign: string): boolean {
    const lastDate = localStorage.getItem(sign);
    const nowDate = new Date().toLocaleDateString();
    const [tYear, tMonth, tDay] = nowDate.split('/');

    if (lastDate) {
      const [year, month, day] = lastDate.split('/');
      /* 今日已记录 */
      if (tYear === year && tMonth === month && tDay === day) {
        return true;
      }
      // 今日未记录
      localStorage.setItem(sign, nowDate);
      return false;
    }
    // 历史从未记录
    localStorage.setItem(sign, nowDate);
    return false;
  }

  /**
   * @param data
   * @param weedOut
   * @description: 判断 rank rankDesc 返回对应结果
   */
  useCurrentInfo(
    data: EndYear.ICurrentAnchor | EndYear.ICurrentAnchorWithUser
  ): {
    rank: number | string;
    rankDesc: string;
  } {
    const { rank, rankDesc } = data;
    return {
      rank:
        rank === 0
          ? [
              NO_QUALIFICATION_FIELD_VALUE,
              NO_PARTICIPATION_FIELD_VALUE,
            ].includes(rankDesc)
            ? '-'
            : '99+'
          : rank > 100
          ? '99+'
          : rank,
      rankDesc,
    };
  }
}
